bitkeeper revision 1.1159.170.18 (419631f46LScNrXRGEL-VrxeFQPSBA)
authorkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Sat, 13 Nov 2004 16:10:28 +0000 (16:10 +0000)
committerkaf24@freefall.cl.cam.ac.uk <kaf24@freefall.cl.cam.ac.uk>
Sat, 13 Nov 2004 16:10:28 +0000 (16:10 +0000)
Clean up keyhandler interface. Now register a new keyhandler with
register_keyhandler() or register_irq_keyhandler().

xen/arch/x86/pdb-stub.c
xen/common/ac_timer.c
xen/common/keyhandler.c
xen/include/xen/keyhandler.h

index de1149e7ffacd34de405ea38a7cbe0e41557596b..a6133b78ae371685e4e5c2f4526611bb4019828f 100644 (file)
@@ -1244,7 +1244,7 @@ void initialize_pdb()
     /* Acknowledge any spurious GDB packets. */
     pdb_put_char('+');
 
-    add_key_handler('D', pdb_key_pressed, "enter pervasive debugger");
+    register_keyhandler('D', pdb_key_pressed, "enter pervasive debugger");
 
     pdb_initialized = 1;
 }
index ddef6d33c391e86599e2674e1ebd2eddbd2f595d..a33498090b90200af06403fb4064c85df7452cd0 100644 (file)
@@ -286,5 +286,5 @@ void __init ac_timer_init(void)
         spin_lock_init(&ac_timers[i].lock);
     }
 
-    add_key_handler('a', dump_timerq, "dump ac_timer queues");
+    register_keyhandler('a', dump_timerq, "dump ac_timer queues");
 }
index 045f8618801b3709723683ddaa6998cc5cff669f..d6eb85250bf11d760c41c1a3d4fc680185d35bd6 100644 (file)
@@ -1,3 +1,6 @@
+/******************************************************************************
+ * keyhandler.c
+ */
 
 #include <xen/keyhandler.h> 
 #include <xen/reboot.h>
 #define KEY_MAX 256
 #define STR_MAX  64
 
-static struct { 
-    key_handler *handler;
-    int          flags;
+static struct {
+    union {
+        keyhandler_t     *handler;
+        irq_keyhandler_t *irq_handler;
+    } u;
+    unsigned int flags;
     char         desc[STR_MAX]; 
 } key_table[KEY_MAX]; 
 
-#define KEYHANDLER_NO_DEFER 0x1
+#define KEYHANDLER_IRQ_CALLBACK 0x1
 
 static unsigned char keypress_key;
 
 void keypress_softirq(void)
 {
-    key_handler  *h;
+    keyhandler_t *h;
     unsigned char key = keypress_key;
-    if ( (h = key_table[key].handler) != NULL )
+    if ( (h = key_table[key].u.handler) != NULL )
         (*h)(key);
 }
 
 void handle_keypress(unsigned char key, struct xen_regs *regs)
 {
-    key_handler  *h;
+    irq_keyhandler_t *h;
 
-    keypress_key = key;
-    if ( (key_table[key].flags & KEYHANDLER_NO_DEFER) &&
-         ((h = key_table[key].handler) != NULL) )
-        ((void (*)(unsigned char, struct xen_regs *))*h)(key, regs);
+    if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK )
+    {
+        if ( (h = key_table[key].u.irq_handler) != NULL )
+            (*h)(key, regs);
+    }
     else
+    {
+        keypress_key = key;
         raise_softirq(KEYPRESS_SOFTIRQ);
+    }
 }
 
-void add_key_handler(unsigned char key, key_handler *handler, char *desc)
+void register_keyhandler(
+    unsigned char key, keyhandler_t *handler, char *desc)
 {
-    key_table[key].handler = handler;
-    key_table[key].flags = 0;
+    ASSERT(key_table[key].u.handler == NULL);
+    key_table[key].u.handler = handler;
+    key_table[key].flags     = 0;
     strncpy(key_table[key].desc, desc, STR_MAX);
     key_table[key].desc[STR_MAX-1] = '\0'; 
 }
 
-void add_key_handler_no_defer(unsigned char key, key_handler *handler,
-                              char *desc)
+void register_irq_keyhandler(
+    unsigned char key, irq_keyhandler_t *handler, char *desc)
 {
-    add_key_handler(key, handler, desc);
-    key_table[key].flags |= KEYHANDLER_NO_DEFER;
+    ASSERT(key_table[key].u.irq_handler == NULL);
+    key_table[key].u.irq_handler = handler;
+    key_table[key].flags         = KEYHANDLER_IRQ_CALLBACK;
+    strncpy(key_table[key].desc, desc, STR_MAX);
+    key_table[key].desc[STR_MAX-1] = '\0'; 
 }
 
 static void show_handlers(unsigned char key)
@@ -60,16 +75,15 @@ static void show_handlers(unsigned char key)
     int i; 
     printk("'%c' pressed -> showing installed handlers\n", key);
     for ( i = 0; i < KEY_MAX; i++ ) 
-        if ( key_table[i].handler != NULL ) 
+        if ( key_table[i].u.handler != NULL ) 
             printk(" key '%c' (ascii '%02x') => %s\n", 
                    (i<33 || i>126)?(' '):(i),i,
                    key_table[i].desc);
 }
 
 
-static void dump_registers(unsigned char key)
+static void dump_registers(unsigned char key, struct xen_regs *regs)
 {
-    struct xen_regs *regs = (struct xen_regs *)get_execution_context();
     extern void show_registers(struct xen_regs *regs); 
     printk("'%c' pressed -> dumping registers\n", key); 
     show_registers(regs); 
@@ -143,20 +157,30 @@ void initialize_keytable(void)
 {
     open_softirq(KEYPRESS_SOFTIRQ, keypress_softirq);
 
-    add_key_handler('d', dump_registers, "dump registers"); 
-    add_key_handler('h', show_handlers, "show this message");
-    add_key_handler('l', print_sched_histo, "print sched latency histogram");
-    add_key_handler('L', reset_sched_histo, "reset sched latency histogram");
-    add_key_handler('q', do_task_queues, "dump task queues + guest state");
-    add_key_handler('r', dump_runq,      "dump run queues");
-    add_key_handler('R', halt_machine,   "reboot machine"); 
+    register_irq_keyhandler(
+        'd', dump_registers, "dump registers"); 
+    register_keyhandler(
+        'h', show_handlers, "show this message");
+    register_keyhandler(
+        'l', print_sched_histo, "print sched latency histogram");
+    register_keyhandler(
+        'L', reset_sched_histo, "reset sched latency histogram");
+    register_keyhandler(
+        'q', do_task_queues, "dump task queues + guest state");
+    register_keyhandler(
+        'r', dump_runq,      "dump run queues");
+    register_keyhandler(
+        'R', halt_machine,   "reboot machine"); 
 
 #ifndef NDEBUG
-    add_key_handler('o', audit_domains_key,  "audit domains >0 EXPERIMENTAL"); 
+    register_keyhandler(
+        'o', audit_domains_key,  "audit domains >0 EXPERIMENTAL"); 
 #endif
 
 #ifdef PERF_COUNTERS
-    add_key_handler('p', perfc_printall, "print performance counters"); 
-    add_key_handler('P', perfc_reset,    "reset performance counters"); 
+    register_keyhandler(
+        'p', perfc_printall, "print performance counters"); 
+    register_keyhandler(
+        'P', perfc_reset,    "reset performance counters"); 
 #endif
 }
index 09e2f234ad56a6951a15cd66114a6d723d2b7b43..e3d49c9086a237378d66e1fd4be7407ccfff2145 100644 (file)
@@ -1,16 +1,35 @@
-/* 
-** We keep an array of 'handlers' for each key code between 0 and 255; 
-** this is intended to allow very simple debugging routines (toggle 
-** debug flag, dump registers, reboot, etc) to be hooked in in a slightly
-** nicer fashion than just editing the serial/keyboard drivers. 
-*/
-struct xen_regs;
+/******************************************************************************
+ * keyhandler.h
+ * 
+ * We keep an array of 'handlers' for each key code between 0 and 255; 
+ * this is intended to allow very simple debugging routines (toggle 
+ * debug flag, dump registers, reboot, etc) to be hooked in in a slightly
+ * nicer fashion than just editing the serial/keyboard drivers. 
+ */
 
-typedef void key_handler(unsigned char key);
+#ifndef __XEN_KEYHANDLER_H__
+#define __XEN_KEYHANDLER_H__
 
-extern void add_key_handler(unsigned char key, 
-                           key_handler *handler, char *desc); 
-extern void add_key_handler_no_defer(unsigned char key, 
-                                     key_handler *handler, char *desc); 
+#include <asm/regs.h>
 
+/*
+ * Register a callback function for key @key. The callback occurs in
+ * softirq context with no locks held and interrupts enabled.
+ */
+typedef void keyhandler_t(unsigned char key);
+extern void register_keyhandler(
+    unsigned char key, keyhandler_t *handler, char *desc); 
+
+/*
+ * Register an IRQ callback function for key @key. The callback occurs
+ * synchronously in hard-IRQ context with interrupts disabled. The @regs
+ * callback parameter points at the interrupted register context.
+ */
+typedef void irq_keyhandler_t(unsigned char key, struct xen_regs *regs);
+extern void register_irq_keyhandler(
+    unsigned char key, irq_keyhandler_t *handler, char *desc); 
+
+/* Inject a keypress into the key-handling subsystem. */
 extern void handle_keypress(unsigned char key, struct xen_regs *regs);
+
+#endif /* __XEN_KEYHANDLER_H__ */